//
//  UIGraphView.m
//  AccuroFit
//
//  Created by Yongfeng Li on 9/10/15.
//  Copyright (c) 2015 Nci Technology Inc. All rights reserved.
//

#import "AppDelegate.h"
#import "UIGraphView.h"

#define _xTextSpace 32
#define _nSwitchCount 7
#define _nBldpBandCount 5

#define _nLeftMargin 50
#define _nRightMargin 20
#define _nTopMargin 15
#define _nBottomMargin 50
#define _nXposOffset 20
#define _nWgtLimitIdx 6 //and 6 is pertange of fat

/*#define _nLeftMargin 0
#define _nRightMargin 0
#define _nTopMargin 0
#define _nBottomMargin 0*/
static short _nBldpSysBand[] = {40, 90, 120, 140, 160,180};
static short _nBldpDiaBand[] = {40, 60, 80, 90, 100, 120};

@implementation UIGraphView {
    CGFloat _fLeftMargin;
    CGFloat _fRightMargin;
    CGFloat _fTopMargin;
    CGFloat _fBottomMargin;
    
    short _nCurtUnit;
    float _goalWgt;
    short _wgtUnit;
    short _nSetUnit;
    
    //Legend
    UIView* _fillLow;
    UIView* _fillMid;
    UIView* _fillHig;
    
    UILabel *_lblLow;
    UILabel *_lblMid;
    UILabel *_lblHig;
    
  BOOL _bIpad;
  BOOL _bIp6p;
  BOOL _bIp6;
  BOOL _bIp5;
  BOOL _bIp4s;
    
    NSMutableArray* _xShowLabelPoints;
    float _fGoalVal;
    
    //CGPoint _ptSelf;
    CGFloat _xViewPos;
    
    CGPoint _ptCenterInit;
  
  BOOL _bBldpCtrl;
  //CGFloat _yBldpPosOff;
  UIColor* _barColor[_nBldpBandCount];
  CAShapeLayer* _bldpBkgdPathLayer;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (id)initWithFrame:(CGRect)frame
{
  if (!(self = [super initWithFrame:frame]))
      return self;
    
  self.backgroundColor = [UIColor clearColor];
  //CGFloat W = frame.size.height;
  _bIp6 = NO;
  _bIp6p = NO; //ipad yes
  _bIp4s = NO;
  _bIpad = frame.size.width > 700;
  if(!_bIpad) {
    _bIp6p = frame.size.width >= 404; //yes:ip-plus
    if(!_bIp6p) {
      _bIp6 = frame.size.width >= 365;
      if(!_bIp6) {
        _bIp5 = frame.size.height > 172;
        _bIp4s = frame.size.height < 171;
      }
    }
  }
  
  _fLeftMargin = _nLeftMargin / (_bIpad?1.0:3.0);
  _fRightMargin = _nRightMargin / (_bIpad?1.0:2.0);
  _fTopMargin = _nTopMargin / (_bIpad?1.0:2.0);
  _fBottomMargin = _nBottomMargin / (_bIpad?1.0:2.0);
    
    self.animationDuration = 0.4f;
    self.hasGrids = YES;
    self.incrementValue = 20;
    self.incrmtxposValue = 10;
    self.barWidth = (frame.size.width - _fLeftMargin - _fRightMargin) / (_nSwitchCount + 2);//20.0;
    self.barAlpha = 1.0;
    self.chartBorderColor = [UIColor blackColor];
    self.gridColor = [UIColor grayColor];
    self.hasYLabels = YES;
    self.yLabelFont = [UIFont fontWithName:@"Helvetica" size:12.0];
    self.yLabelColor = [UIColor colorWithWhite:1.0 alpha:1.0];//[UIColor lightGrayColor];
    self.xLabelFont = [UIFont fontWithName:@"Helvetica" size:11.0];
    self.xLabelColor = [UIColor lightGrayColor];
    self.xLabelType = GraphViewXLabelTypeVerticle;
  
  //self.barTextFont = [UIFont systemFontOfSize:12];//[UIFont fontWithName:@"Helvetica" size:9.0];
  self.barTextFont = [UIFont boldSystemFontOfSize:12.8];
  self.barTextColor = [UIColor whiteColor];
    self.barTextType = GraphViewBarTextTypeTop;
    
    _barPathLayers			= [[NSMutableArray alloc] init];
    _barHeights				= [[NSMutableArray alloc] init];
    _barHoriPos				= [[NSMutableArray alloc] init];
    _barLabels				= [[NSMutableArray alloc] init];
    _barTexts				= [[NSMutableArray alloc] init];
    
    _hrtHeights              = [[NSMutableArray alloc] init];
    
    // Grid
    _gridLayer = [CALayer layer];
    [self.layer addSublayer:_gridLayer];
    _gridLayer_x = [CALayer layer];
    [self.layer addSublayer:_gridLayer_x];
    
    //bar & curve
    _barLayer = [CALayer layer];
    [self.layer addSublayer:_barLayer];
    
    _borderLayer = [CALayer layer];
    [self.layer addSublayer:_borderLayer];
    
    _yLabelView = [[UIView alloc] init];
    _yLabelView.alpha	 = 0.0;
    [self addSubview:_yLabelView];
    
    _xLabelView = [[UIView alloc] init];
    _xLabelView.alpha	 = 0.0;
    [self addSubview:_xLabelView];
    
    _barTextView = [[UIView alloc] init];
    _barTextView.alpha = 0.0;
    [self addSubview:_barTextView];
    
    _nCurtUnit = 0;
    _goalWgt = 0.0;
    _wgtUnit = 0;
    _nSetUnit = 2;
    
    //meas unit text
    _lblMeasUnit = [[UILabel alloc] initWithFrame:CGRectMake(2, (_bIpad?-12:-15) - 20, (_bIpad?70:35), 28)];
    _lblMeasUnit.backgroundColor = [UIColor clearColor];
    _lblMeasUnit.textColor = [UIColor orangeColor];
    _lblMeasUnit.textAlignment = NSTextAlignmentRight;
    _lblMeasUnit.font = [UIFont boldSystemFontOfSize:17];
    _lblMeasUnit.text = @"kg";//NSLocalizedString(@"kcalory", nil);//@"minute", nil);
    [self addSubview:_lblMeasUnit];
    
    //Legend
    //[self createLegends:frame.size.width];
    _xShowLabelPoints = [[NSMutableArray alloc] init];
    
    _ptCenterInit = self.center;
    
  [self createBldpBandInfo];
  
  self.layer.frame = self.frame;
  self.layer.backgroundColor = [UIColor clearColor].CGColor;
  
  _topValue = 0;
  _barWidthRatio = 0;
  _barHeightRatio = 0;
  
  return self;
}

- (void) createBldpBandInfo
{
  /*_barColor[0] = [[UIColor blueColor] colorWithAlphaComponent:0.35];
  _barColor[1] = [[UIColor greenColor] colorWithAlphaComponent:0.35];
  _barColor[2] = [[UIColor yellowColor] colorWithAlphaComponent:0.35]; 
  _barColor[3] = [[UIColor orangeColor] colorWithAlphaComponent:0.35];
  _barColor[4] = [[UIColor redColor] colorWithAlphaComponent:0.35];*/
    
    _barColor[0] = [UIColor colorWithRed:213.0/255 green:48.0/255 blue:147.0/255 alpha:1.0];
    //_barColor[1] = [UIColor colorWithRed:213.0/255 green:48.0/255 blue:147.0/255 alpha:1.0];
    _barColor[1] = [UIColor colorWithRed:246.0/255 green:230.0/255 blue:101.0/255 alpha:1.0];
    _barColor[2] = [UIColor colorWithRed:95.0/255 green:218.0/255 blue:83.0/255 alpha:1.0];
    _barColor[3] = [UIColor colorWithRed:53.0/255 green:182.0/255 blue:229.0/255 alpha:1.0];
    _barColor[4] = [UIColor colorWithRed:198.0/255 green:150.0/255 blue:215.0/255 alpha:1.0];
}

- (void) createLegends:(CGFloat)W
{
    CGFloat xPos = W / 6;
    CGFloat offSet = W / 3 - W / 6;
    CGFloat lenHgt = 16;;
    if(W < 1000) {
        xPos += 12;
        offSet += 30;
        if(W < 320) {
            lenHgt = 12;
        }
    }
    //low
    _fillLow = [[UIView alloc] init];
    [_fillLow setFrame:CGRectMake(xPos, -22, 30, lenHgt)];
    [_fillLow setBackgroundColor:[UIColor blueColor]];
    [[_fillLow layer] setCornerRadius:1];
    [self addSubview:_fillLow];
    
    _lblLow = [[UILabel alloc] initWithFrame:CGRectMake(xPos+32, -22, 70, lenHgt)];
    _lblLow.backgroundColor = [UIColor clearColor];
    _lblLow.textColor = [UIColor grayColor];
    _lblLow.textAlignment = NSTextAlignmentLeft;
    _lblLow.font = [UIFont boldSystemFontOfSize:13.5];
    _lblLow.text = @"Low HR";
    [self addSubview:_lblLow];
    
    //mid
    xPos += offSet;
    _fillMid = [[UIView alloc] init];
    [_fillMid setFrame:CGRectMake(xPos, -22, 30, lenHgt)];
    [_fillMid setBackgroundColor:[UIColor colorWithRed:0.0 green:0.45 blue:0.01 alpha:0.75]];
    [[_fillMid layer] setCornerRadius:1];
    [self addSubview:_fillMid];
    
    _lblMid = [[UILabel alloc] initWithFrame:CGRectMake(xPos+32, -22, 70,lenHgt)];
    _lblMid.backgroundColor = [UIColor clearColor];
    _lblMid.textColor = [UIColor grayColor];
    _lblMid.textAlignment = NSTextAlignmentLeft;
    _lblMid.font = [UIFont boldSystemFontOfSize:13.5];
    _lblMid.text = @"Mid HR";
    [self addSubview:_lblMid];
    
    //hig
    xPos += offSet;
    _fillHig = [[UIView alloc] init];
    [_fillHig setFrame:CGRectMake(xPos, -22, 30, lenHgt)];
    [_fillHig setBackgroundColor:[UIColor orangeColor]];
    [[_fillHig layer] setCornerRadius:1];
    [self addSubview:_fillHig];
    
    _lblHig = [[UILabel alloc] initWithFrame:CGRectMake(xPos+32, -22, 70, lenHgt)];
    _lblHig.backgroundColor = [UIColor clearColor];
    _lblHig.textColor = [UIColor grayColor];
    _lblHig.textAlignment = NSTextAlignmentLeft;
    _lblHig.font = [UIFont boldSystemFontOfSize:13.5];
    _lblHig.text = @"High HR";
    [self addSubview:_lblHig];
    
    //hig
    
}

/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
 // Drawing code
 }
 */

- (void) reloadDataWithColor:(UIColor *)lColor
{
  //_yBldpPosOff = 0;
  BOOL bBldp = _nSetUnit == 201 || _nSetUnit == 202;
  _bBldpCtrl = bBldp;
  
  if (!_dataSource)
    return;
  if(_nSetUnit == _nWgtLimitIdx)
    _lblMeasUnit.text = @"%";
  else if(_nSetUnit < 6)
    _lblMeasUnit.text = (_nSetUnit==2)?@"kg":@"kg";
  else
      _lblMeasUnit.text = @"";
    
  if(_nSetUnit == 253 || _nSetUnit == 254) {
    _fLeftMargin = 1;
    _fGoalVal = (_nSetUnit == 253)?[_dataSource goalSteps]: [_dataSource goalDists];
  }
    
  _numberOfBars = [_dataSource numberOfBarsInBarChart:self];
  _bDrawCurve = _numberOfBars > _nSwitchCount;
  
  //if(bBldp && _numberOfBars != 0)
    //_bDrawCurve = YES;
    
  [_barHeights removeAllObjects];
  [_hrtHeights removeAllObjects];
  [_barLabels removeAllObjects];
  [_barTexts removeAllObjects];
  [_barHoriPos removeAllObjects];
    
  // Collect some data
  for (NSInteger i = 0; i < _numberOfBars; i++) {
    if(_nSetUnit == 254) {
      CGFloat fDist = [_dataSource barChart:self distanceAtIndex:i];
      NSString* sFmt = (fDist > 0.1)?@"%.1f":@"%.2f";
      if(fDist < 0.001)
        sFmt = @"%.5f";
      else if(fDist < 0.01)
        sFmt = @"%.3f";
      NSString* sDist = [NSString stringWithFormat:sFmt, fDist];
      [_barHeights addObject:[NSNumber numberWithFloat:fDist]];
      //[_barTexts addObject:[_dataSource barChart:self distTxtForBarAtIndex:i]];
      [_barTexts addObject:sDist];
    }
    else {
      if(bBldp) {
        if(_nSetUnit == 202) {
          [_barHeights addObject:[NSNumber numberWithFloat:[_dataSource barChart:self valueForBdplAtIndex:i]]];
          [_barTexts addObject:[_dataSource barChart:self textForLdpAtIndex:i]];
        }
        else {
          [_barHeights addObject:[NSNumber numberWithFloat:[_dataSource barChart:self valueForBarAtIndex:i]]];
          [_barTexts addObject:[_dataSource barChart:self textForBarAtIndex:i]];
        }
      }
      else {
        CGFloat fVal = [_dataSource barChart:self valueForBarAtIndex:i];
        NSString* sFmt =  (_nSetUnit<=_nWgtLimitIdx)?@"%.1f": @"%.0f";
        if(fVal < 1)
          sFmt = @"%.4f";
        else if(fVal < 10)
          sFmt = @"%.3f";

        NSString* sVal = [NSString stringWithFormat:sFmt, fVal];
        [_barHeights addObject:[NSNumber numberWithFloat:fVal]];
        //[_barTexts addObject:[_dataSource barChart:self textForBarAtIndex:i]];
        [_barTexts addObject:sVal];
      }
    }
    if(_nSetUnit == 251) { //heart rate
      float fHrate = [_dataSource barChart: self lTimeForBarAtIndex:i];
      if([_dataSource barChart: self hTimeForBarAtIndex:i] >fHrate)
        fHrate = [_dataSource barChart: self hTimeForBarAtIndex:i];
      [_hrtHeights addObject:[NSNumber numberWithFloat:fHrate]];
    }
    else if(_nSetUnit == 250) { //cal burned
      float fCalories = [_dataSource barChart: self calBurnedForBarAtIndex:i];
      [_hrtHeights addObject:[NSNumber numberWithFloat:fCalories]];
    }
    if (_bDrawCurve) {
      [_barHoriPos addObject:[NSNumber numberWithFloat:[_dataSource barChart:self xposForBarAtIndex:i]]];
    }
    if (_dataSource && [_dataSource respondsToSelector:@selector(barChart:xLabelForBarAtIndex:)]) {
      NSString* sLblTxt = [_dataSource barChart:self xLabelForBarAtIndex:i];
      if(sLblTxt != nil)
        [_barLabels addObject:sLblTxt];
    }
        //if (_nSetUnit != 254 && _dataSource && [_dataSource respondsToSelector:@selector(barChart:textForBarAtIndex:)])
            
  }
  
  _maxHeight = [NSNumber numberWithInteger:100];
  _minHeight = [NSNumber numberWithInteger:0];
  
  if(_numberOfBars > 0) {
    _maxHeight		= [_barHeights valueForKeyPath:@"@max.self"];
    _minHeight		= [_barHeights valueForKeyPath:@"@min.self"];
    
    _maxWidth		= [_barHoriPos valueForKeyPath:@"@max.self"];
    _minWidth		= [_barHoriPos valueForKeyPath:@"@min.self"];
  }
  else {
    _maxHeight = [NSNumber numberWithInteger:(_nSetUnit == 2)? 400:200];
    _minWidth = [NSNumber numberWithFloat:0.0];
    _maxWidth = [NSNumber numberWithFloat:1.0];
    _minWidth = [NSNumber numberWithFloat:0.0];
  }
  
  if(!_bBldpCtrl) {
    if(_numberOfBars > 0) {
      if(_nSetUnit == 251 || _nSetUnit == 250) {
        NSNumber* fMaxHrate = [_hrtHeights valueForKeyPath:@"@max.self"];
        if(fMaxHrate.floatValue > _maxHeight.floatValue)
          _maxHeight = fMaxHrate;
      }
        
    }
  }
  else {
    if(_nSetUnit == 201) { //h val
      _topValue = 180;
      _maxHeight = [NSNumber numberWithFloat:180];
      _minHeight = [NSNumber numberWithFloat:40];
      
      self.incrementValue = 20;
      //_yBldpPosOff = 20;
    }
    else {
      _topValue = 120;
      _maxHeight = [NSNumber numberWithFloat:120.0];
      _minHeight = [NSNumber numberWithFloat:40];
      self.incrementValue = 20;
      //_yBldpPosOff = 20;
    }
    //[self drawBldpColorBand];
    //return;
  }
    
  //self.incrementValue = (_nSetUnit == 2)? 50 : 100;
    
    
  self.incrementValue = (_nSetUnit == 1)? 10 : 20;
  _rightValue      = _maxWidth.floatValue - _minWidth.floatValue;

  if(_nSetUnit == _nWgtLimitIdx) {
    _topValue = 60;
    self.incrementValue = 20;
  }
  else if(_nSetUnit == 199) {
    _topValue		= self.incrementValue + (self.incrementValue - (_maxHeight.integerValue % self.incrementValue)) + _maxHeight.integerValue;
    //_rightValue      = _maxWidth.integerValue - _minWidth.integerValue + 1.0;
  }
  else if(_nSetUnit == 250) { //cal burned
    if(_maxHeight.floatValue < 1) {
      _topValue = 1;
      self.incrementValue = 1;
    }
    else {
      _topValue = (_maxHeight.floatValue * 1.25 + 1.0);
      //_topValue = 5 * (int)(_topValue / 4);
      if(_topValue == 0)
        _topValue = (int)(_maxHeight.floatValue + 1);
        if(_topValue >= 5)
          self.incrementValue = _topValue / 4;
        else
          self.incrementValue = 1;
      }
      if(_numberOfBars == 0) {
        self.incrementValue = 1;
        _topValue = 5;
      }
  }
  else if(_nSetUnit == 251) {
    if(_maxHeight.floatValue < 1) {
      _topValue = 1;
      self.incrementValue = 1;
    }
    else {
      _topValue = (_maxHeight.floatValue * 1.25 + 1.0);
      if(_topValue >= 4)
        self.incrementValue = _topValue / 4;
      else
        self.incrementValue = 1;
    }
    if(_numberOfBars == 0) {
      self.incrementValue = 5;
      _topValue = 30;
    }
  }
  else if(bBldp) { //bldp hval
      ;
  }
  else if(_nSetUnit == 253) {
    float fGoalSteps = _fGoalVal;//[_dataSource goalSteps];
    _topValue = (NSInteger)([[_barHeights valueForKeyPath:@"@max.self"] floatValue] * 1.2 + 0.5);
    if(fGoalSteps > 0 && _topValue < fGoalSteps)
      _topValue = fGoalSteps * 1.25;
    /*if(_topValue < 1)
    _topValue = [_dataSource goalSteps] * 2;
    if(_topValue < [_dataSource goalSteps])
      _topValue = [_dataSource goalSteps] * 1.25;*/
  }
  else if(_nSetUnit == 254) {
    float fGoalDists = _fGoalVal;//[_dataSource goalDists];
    _topValue =  (NSInteger)([[_barHeights valueForKeyPath:@"@max.self"] floatValue] * 1.2 + 0.5);
    if(fGoalDists > 0 && _topValue < fGoalDists)
      _topValue = fGoalDists * 1.25;
    //if(_topValue < 1)
      //_topValue = 1;
  }
  else {
    if(_numberOfBars == 0) {
      self.incrementValue = (_nSetUnit == 1)? 50 : 100;
      _topValue = (_nSetUnit == 1)? 200:400;
    }
    else {
      self.incrementValue = (_nSetUnit == 1)? 25 : 50;
      //self.incrementValue = (_nSetUnit == 1)? 50 : 100;
      _topValue = (_nSetUnit == 1)? 200:400;
    }
  }
    
  // Round up to the next increment value
  if (_dataSource) 	{
    // Find max height of the x Labels based on the angle of rotation of the text
    switch (self.xLabelType) {
      case GraphViewXLabelTypeVerticle:
      default:
        _xLabelRotation = 90.0;
        break;
            
      case GraphViewXLabelTypeHorizontal:
        _xLabelRotation = 0.0;
        break;
              
      case GraphViewXLabelTypeAngled:
        _xLabelRotation = 45.0;
        break;
    }
        
    for (NSString *label in _barLabels) {
      //CGSize labelSize = [label sizeWithFont:self.xLabelFont];
      CGSize labelSize = [label sizeWithAttributes:@{NSFontAttributeName: self.xLabelFont}];
      CGFloat labelHeightWithAngle = sin(DEGREES_TO_RADIANS(_xLabelRotation)) * labelSize.width;
            
      if (labelSize.height > labelHeightWithAngle)	{
        _xLabelMaxHeight = (_xLabelMaxHeight > labelSize.height) ? _xLabelMaxHeight : labelSize.height;
      }
      else {
        _xLabelMaxHeight = (_xLabelMaxHeight > labelHeightWithAngle) ? _xLabelMaxHeight : labelHeightWithAngle;
      }
    }
        
    /*     Begin Drawing     */
    // Set Frames
    //CGSize yLabelSize		= self.hasYLabels ? [[NSString stringWithFormat:@"%i", (int)_topValue] sizeWithFont:self.yLabelFont] : CGSizeZero;
    CGSize yLabelSize		= self.hasYLabels ? [[NSString stringWithFormat:@"%i", (int)_topValue] sizeWithAttributes:@{NSFontAttributeName:self.yLabelFont}] : CGSizeZero;
    _yLabelView.frame		= CGRectMake(0.0, 0.0, self.hasYLabels ? yLabelSize.width + 5.0 : 0.0, self.bounds.size.height);
        
    _xLabelView.frame		= CGRectMake(_yLabelView.frame.origin.x + _yLabelView.frame.size.width,
                                    self.bounds.size.height - _xLabelMaxHeight,
                                    self.bounds.size.width/* - (_yLabelView.frame.origin.x + _yLabelView.frame.size.width)*/,
                                    _xLabelMaxHeight);

    _gridLayer.frame		= CGRectMake(_yLabelView.frame.origin.x + _yLabelView.frame.size.width,
                                    0.0,
                                    self.bounds.size.width - (_yLabelView.frame.origin.x + _yLabelView.frame.size.width),
                                     self.bounds.size.height - (bBldp?0.0 : (_xLabelMaxHeight > 0.0 ? /*(_xLabelMaxHeight + 5.0)*/0.0 : 0.0)));
    _gridLayer_x.frame		= /*_gridLayer.frame;*/
    CGRectMake(_gridLayer.frame.origin.x - _nXposOffset / (_bIpad?3.0 : 1.7),
              self.bounds.size.height - _fBottomMargin,
              _gridLayer.frame.size.width/*self.bounds.size.width*/,
              _fBottomMargin);
        
    _barLayer.frame			=  _gridLayer.frame;
    _borderLayer.frame		= _gridLayer.frame;
    _barTextView.frame		= _gridLayer.frame;
    //_gridLayer.bounds = self.frame;
    
    if(_barHeightRatio == 0 && _topValue > 0) {
      if(bBldp) {
        //CGFloat fHgt = _gridLayer.bounds.size.height;
        _barHeightRatio = (_gridLayer.bounds.size.height - _fTopMargin - _fBottomMargin)  / (_maxHeight.floatValue - _minHeight.floatValue);
      }
      else if(_topValue != 0) {
        _barHeightRatio = (_gridLayer.bounds.size.height - _fTopMargin - _fBottomMargin)  / (CGFloat)_topValue;
      }
      else {
        _barHeightRatio = 1;
      }
    
      if(_rightValue <= 0)
        _rightValue = 1;
      
      
      if (_barHeightRatio < 1 && !bBldp) {
        _barHeightRatio = (_gridLayer.bounds.size.height - _fTopMargin - _fBottomMargin) / (CGFloat)_topValue;
      }
      
      if(_barWidthRatio != 0 && (_nSetUnit == 253 || _nSetUnit == 254)) {
        _barWidthRatio = (_gridLayer.bounds.size.width - _fLeftMargin - _fRightMargin -_nXposOffset * (_bIpad?1.0:0.7)) / (CGFloat)_rightValue;
        if (_barWidthRatio < 1)
          _barWidthRatio = (_gridLayer.bounds.size.width - _fTopMargin - _fBottomMargin - self.incrmtxposValue * 2) / (CGFloat)_rightValue;
      }
    }
    
    if(_nSetUnit <= _nWgtLimitIdx) {
      if(_topValue != 0)
        _barHeightRatio = (_gridLayer.bounds.size.height - _fTopMargin - _fBottomMargin)  / (CGFloat)_topValue;
    }
    
    if(_nSetUnit != 253 && _nSetUnit != 254) {
      _barWidthRatio = (_gridLayer.bounds.size.width - _fLeftMargin - _fRightMargin -_nXposOffset * (_bIpad?1.0:0.7)) / (CGFloat)_rightValue;
      if (_barWidthRatio < 1)
        _barWidthRatio = (_gridLayer.bounds.size.width - _fTopMargin - _fBottomMargin - self.incrmtxposValue * 2) / (CGFloat)_rightValue;
    }
    //if(_topValue == 0)
      //return;
        
    // Draw dem stuff
    [self setupBorders];
    [self drawBorders];
  
        
    @autoreleasepool {
      if(_bDrawCurve) {
        [self drawCurve];
        [self animateBarAtIndex:0];
      }
      else {
        [self setupBars];
        [self animateBarAtIndex:0];
      }
    }
        
        
    if (self.hasGrids) {
      [self setupGrid];
      [self drawGrid];
    }
        
      [self setupYAxisLabels:lColor];
      [self setupXAxisLabels:lColor];
        
    if(!_bDrawCurve)
      [self setupBarTexts];
      
    //[self.layer setNeedsDisplay];
  }
}

- (void) drawRect:(CGRect)rect
{
  return;
  /*if(!_bBldpCtrl)
    return;
  
  CGContextRef ctx = UIGraphicsGetCurrentContext();
  CGMutablePathRef path = CGPathCreateMutable();
  CGPathMoveToPoint(path, NULL, 20, 20);
  CGPathAddLineToPoint(path, NULL, 200, 300);
  //2.3把路径添加到上下文中
  //把绘制直线的绘图信息保存到图形上下文中
  CGContextAddPath(ctx, path);
  CGContextStrokePath(ctx);
  
  CGFloat barWid = rect.size.width - _fLeftMargin - _fRightMargin;
  for (int i=0; i<=_nBldpBandCount; i++) {
    CGFloat barHgt = 45;
    CGContextSetFillColorWithColor(ctx, _barColor[i].CGColor);
    //CGFloat x = _fLeftMargin;
    CGFloat y = self.frame.size.height - i * 30;
    CGRect barRect = CGRectMake(_fLeftMargin, y, barWid,  barHgt);
    
    CGContextAddRect(ctx, barRect);
    CGContextFillPath(ctx);
    
    CGContextStrokePath(ctx);
  }
  
  //[_barLayer addSublayer:bandColorPathLayer];
  //[_barPathLayers addObject:bandColorPathLayer];
  
  CGPathRelease(path);*/
}

- (CGFloat) getyBandPos:(int)nIdx bdpSys:(BOOL)bBdpSys
{
  CGFloat yPos = 0;
  CGFloat yOff = _fBottomMargin * 0.7;
  CGFloat yMinValOff = _minHeight.floatValue;
  
  short nBdpVal = bBdpSys? _nBldpSysBand[nIdx]: _nBldpDiaBand[nIdx];
  
  //CGFloat gridUnit		= _barHeightRatio;
  //CGFloat gridSeperation	= gridUnit * (CGFloat)self.incrementValue;
  
  yPos	= (nBdpVal - yMinValOff)* _barHeightRatio + yOff;
  
  return CGRectGetMaxY(_borderLayer.bounds) - _fTopMargin - yPos;
}

- (void) drawBldpColorBand:(CGContextRef)ctx
{
  if(!_bBldpCtrl)
    return;
  
  BOOL bBldpSys = _nSetUnit == 201;// || _nSetUnit == 202;
  //if(!bBldpSys)
    //return;
  for (int i=1; i<=_nBldpBandCount; i++) {
    CGContextSetFillColorWithColor(ctx, _barColor[i-1].CGColor);
    CGFloat xPos = _fLeftMargin + _nXposOffset / (_bIpad?0.545:(_bIp6?0.605:0.605));
    CGFloat yPos = [self getyBandPos:i bdpSys:bBldpSys];
    CGFloat fHgt = yPos - [self getyBandPos:i-1 bdpSys:bBldpSys];
    CGFloat fWid = CGRectGetMaxX(_borderLayer.bounds) - _fRightMargin - xPos * (_bIpad?0.70:(_bIp6?0.50:0.50));
    
    CGRect barRect = CGRectMake(xPos, yPos-fHgt, fWid, fHgt);
    
    CGContextAddRect(ctx, barRect);
    CGContextFillPath(ctx);
    
    CGContextStrokePath(ctx);
  }
  //[self setNeedsDisplay];
  return;
  
  /*_bldpBkgdPathLayer                    = [CAShapeLayer layer];
  _bldpBkgdPathLayer.frame              = _borderLayer.bounds;
  _bldpBkgdPathLayer.bounds             = _borderLayer.bounds;
  _bldpBkgdPathLayer.geometryFlipped    = YES;
  //_bldpBkgdPathLayer       = self.chartBorderColor.CGColor;
  //_bldpBkgdPathLayer.fillColor        = nil;
  _bldpBkgdPathLayer.lineJoin           = kCALineJoinBevel;
  //_bldpBkgdPathLayer.lineCap            = kCGLineCapSquare;
  
  for (int i=1; i<=_nBldpBandCount; i++) {
    UIColor* colBand = _barColor[i-1];
    [colBand setStroke];
    [colBand setFill];
    
    CGFloat xPos = _fLeftMargin + _nXposOffset / (_bIpad?1.5:(_bIp6?2.2:2.5));;
    CGFloat yPos = [self getyBandPos:i bdpSys:bBldpSys];
    //CGPoint pt	= CGPointMake(xPos, yPos - fWidth/2);
    
    CGFloat fHgt = yPos - [self getyBandPos:i-1 bdpSys:bBldpSys];
    CGFloat fWid = CGRectGetMaxX(_borderLayer.bounds) - _fRightMargin - xPos;
    
    //[path moveToPoint:pt];
    //pt.x = CGRectGetMaxX(_borderLayer.bounds) - _fRightMargin;
    //pt.y += 30;
    //[path addLineToPoint:pt];
    UIBezierPath *path		= [UIBezierPath bezierPathWithRect:CGRectMake(xPos, yPos-fHgt, fWid, fHgt)];
    path.lineCapStyle = kCGLineCapButt;
    [path closePath];
    [path fill];
    [path stroke];
    //[path strokeWithBlendMode:kCGBlendModeNormal alpha:0.5];
    
    _bldpBkgdPathLayer.strokeColor = [colBand colorWithAlphaComponent:0.35].CGColor;
    _bldpBkgdPathLayer.fillColor = [colBand colorWithAlphaComponent:0.35].CGColor;
    _bldpBkgdPathLayer.path = path.CGPath;
    _bldpBkgdPathLayer.lineWidth = fHgt;
    //[_bldpBkgdPathLayer
    
    [_borderLayer addSublayer:_bldpBkgdPathLayer];
    [_barLayer addSublayer:_bldpBkgdPathLayer];
    [_barPathLayers addObject:_bldpBkgdPathLayer];
  }*/
}

- (void) updateData:(float)fBurnedVal
{
  _numberOfBars = 1;
  _bDrawCurve = _numberOfBars > _nSwitchCount;
  if(_bBldpCtrl)
    _bDrawCurve = YES;
    
  [_barHeights removeAllObjects];
  [_hrtHeights removeAllObjects];
  [_barLabels removeAllObjects];
  [_barTexts removeAllObjects];
  [_barHoriPos removeAllObjects];
    
  _topValue = 5;
  self.incrementValue = 1;
    
  // Collect data hgt
  if(fBurnedVal > _topValue) {
    _topValue = ((int)(fBurnedVal + 5)) / 5  * 5;
    _maxHeight = [NSNumber numberWithFloat:_topValue];
    _barHeightRatio  = (_gridLayer.bounds.size.height - _fTopMargin - _fBottomMargin)  / (CGFloat)_topValue;
    self.incrementValue = _topValue / 5;
  }
  //_maxHeight = [NSNumber number _topValue;
  [_barHeights addObject:[NSNumber numberWithFloat:fBurnedVal]];
  [_hrtHeights addObject:[NSNumber numberWithFloat:fBurnedVal]];
  [_barTexts addObject:[NSString stringWithFormat:@"%.2f", fBurnedVal]];
    
  @autoreleasepool {
    [self setupBars];
    [self animateBarAtIndex:0];
  }
    
  [self setupGrid];
  [self drawGrid];
    
    [self setupYAxisLabels:nil];
    [self setupXAxisLabels:nil];
    
  [self setupBarTexts];
  [self.layer setNeedsDisplay];
}

#pragma mark Borders

- (void)setupBorders
{
  if (_borderPathLayer != nil) {
    [_borderPathLayer removeFromSuperlayer];
    _borderPathLayer = nil;
  }
    
  CGFloat fOffset =  _nXposOffset /(_bIpad?1.5:2.5);//_gridLayer.bounds.size.width / 50.0;
  CGPoint bottomLeft 	=  CGPointMake(CGRectGetMinX(_borderLayer.bounds) + _fLeftMargin + fOffset, CGRectGetMinY(_borderLayer.bounds) + _fBottomMargin);
  CGPoint bottomRight = CGPointMake(CGRectGetMaxX(_borderLayer.bounds) - _fRightMargin, CGRectGetMinY(_borderLayer.bounds) + _fBottomMargin);
  CGPoint topLeft		= CGPointMake(CGRectGetMinX(_borderLayer.bounds) + _fLeftMargin + fOffset, CGRectGetMaxY(_borderLayer.bounds) - _fTopMargin);
  //CGPoint topRight	= CGPointMake(CGRectGetMaxX(_borderLayer.bounds) - _fRightMargin, CGRectGetMaxY(_borderLayer.bounds) - _fTopMargin);
    
  //CGPoint bottomLeft 	= CGPointMake(CGRectGetMinX(_borderLayer.frame), CGRectGetMinY(_borderLayer.frame));
  //CGPoint bottomRight = CGPointMake(CGRectGetMaxX(_borderLayer.frame), CGRectGetMinY(_borderLayer.frame));
  //CGPoint topLeft		= CGPointMake(CGRectGetMinX(_borderLayer.frame), CGRectGetMaxY(_borderLayer.frame));
  //CGPoint topRight    = CGPointMake(CGRectGetMaxX(_borderLayer.frame), CGRectGetMaxY(_borderLayer.frame));
    
  UIBezierPath *path	= [UIBezierPath bezierPath];
     
  if(_nSetUnit != 253 && _nSetUnit != 254) {
    [path moveToPoint:bottomLeft];
    [path addLineToPoint:topLeft];
  }
  else {
    bottomLeft.x -= _nLeftMargin / 2;
    if(_nSetUnit == 254) {
      bottomLeft.x += self.barWidth * 0.35;
      bottomRight.x += self.barWidth * 0.55;
    }
    if(_nSetUnit == 253 && _bIp6p && ![AppDelegate isLanguageChines]) {
      bottomLeft.x += 15;
      bottomRight.x += 15;
    }
  }
  [path moveToPoint:bottomLeft];
  [path addLineToPoint:bottomRight];
  
  _borderPathLayer                    = [CAShapeLayer layer];
  _borderPathLayer.frame              = _borderLayer.bounds;
  _borderPathLayer.bounds             = _borderLayer.bounds;
  _borderPathLayer.geometryFlipped    = YES;
  _borderPathLayer.path               = path.CGPath;
  _borderPathLayer.strokeColor        = [UIColor colorWithRed:0.00 green:0.53 blue:0.28 alpha:1.00].CGColor;//self.gridColor.CGColor;
  //_borderPathLayer.strokeColor       = self.chartBorderColor.CGColor;
  _borderPathLayer.fillColor          = nil;
  _borderPathLayer.lineWidth          = 0.5f;
  _borderPathLayer.lineJoin           = kCALineJoinBevel;
    
  [_borderLayer addSublayer:_borderPathLayer];
}

- (void)drawBorders
{
    if (self.animationDuration == 0.0)
        return;
    
    [_borderPathLayer removeAllAnimations];
    
    CABasicAnimation *pathAnimation	= [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration			= self.animationDuration;
    pathAnimation.fromValue			= [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue			= [NSNumber numberWithFloat:0.4f];
    [_borderPathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];

  //[_gridLayer setNeedsDisplay];
}

#pragma mark Bars

- (void)setupBars
{
    // Clear all bars for each drawing
  for (CAShapeLayer *layer in _barPathLayers) {
      if (layer != nil) {
        [layer removeFromSuperlayer];
      }
  }
  //[_barLayer removeAllAnimations];
  [_barPathLayers removeAllObjects];
    
  CGFloat barHeightRatio	= _barHeightRatio;//_barLayer.bounds.size.height / (CGFloat)_topValue;
  CGFloat	xPos			= _barLayer.bounds.size.width / (_numberOfBars + 1) - _fLeftMargin + _nXposOffset / (_bIpad?0.28:0.8);
  if(_nSetUnit == 253 || _nSetUnit == 254) {
    /*if(_nSetUnit == 253)
      xPos += _nLeftMargin / (_bIpad?0.75:2.5); //self.barWidth;
    else
      xPos -= _nLeftMargin / (_bIpad?0.75:3.0);*/
    xPos = self.incrmtxposValue + _fLeftMargin + _nXposOffset + self.barWidth * (_bIpad?0.68:_bIp6p?0.21:(_bIp6?0.21:(_bIp4s?-0.12:-0.15)));
    if(_nSetUnit == 253)
      xPos += self.barWidth * (_bIpad? 0.50: (_nSetUnit == 254)?0.45:0.05);
    else
      xPos += self.barWidth * (_bIpad? 0.60: (_nSetUnit == 254)?0.45:0.05);
  }

  float fWgtGoal = _goalWgt;
  if(_nSetUnit != 255 && _nSetUnit != _wgtUnit) {
    if(_nSetUnit == 2)
      fWgtGoal *= _KgtoLb;
    else
      fWgtGoal /= _KgtoLb;
  }
    
  for (NSInteger i = 0; i < _numberOfBars; i++)	{
    if(([_barHeights objectAtIndex:i]) == nil) {
      if(_nSetUnit == 253)
        xPos += self.barWidth * ( _bIp6p?1.20: 1.22);
      else if(_nSetUnit == 254)
        xPos += self.barWidth * ( _bIp6p?1.20: 1.22);
      else
        xPos += _barLayer.bounds.size.width / (_numberOfBars + 1);
      continue;
    }
    
    CGPoint bottom					= CGPointMake(xPos, _barLayer.bounds.origin.y + _fBottomMargin);
    float fHgt = ((NSNumber*)[_barHeights objectAtIndex:i]).floatValue * barHeightRatio + _fBottomMargin;
    //if(fHgt > self.frame.size.height)
      //fHgt = self.frame.size.height - _nTopMargin;
    //if(fHgt > _barLayer.bounds.size.height)
      //fHgt =  _barLayer.bounds.size.height - _nTopMargin;
    CGPoint top						= CGPointMake(xPos, fHgt);
    
    //if(_nSetUnit == 201) //bldp hvak
        //bottom.y = [_dataSource barChart:self lPresForBarAtIndex:i] * barHeightRatio + _fBottomMargin;
    if(_nSetUnit == 201 || _nSetUnit == 202) {//bldp value
      //float bOffset = _minHeight.floatValue;
      top.y -= _minHeight.floatValue * barHeightRatio;
    }
      
    UIBezierPath *path				= [UIBezierPath bezierPath];
    [path moveToPoint:bottom];
    [path addLineToPoint:top];
        
    float fMeasVal = ((NSNumber *)[_barHeights objectAtIndex:i]).floatValue;
    //BOOL bLessGoal = fWgtGoal == 0 || fWgtVal <= fWgtGoal;
    BOOL bLessGoal = _fGoalVal > 0 && fMeasVal < _fGoalVal;
        
//    UIColor *barColor = [UIColor orangeColor];//[UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1.0];
          UIColor *barColor = [UIColor colorWithRed:0.0 green:0.55 blue:0.74 alpha:1.0];
    if ((bLessGoal && _nSetUnit > 200) && _dataSource && [_dataSource respondsToSelector:@selector(barChartColor)])
      barColor = [_dataSource barChartColor];
        
        
    CGFloat fBarWid = self.barWidth;
    CAShapeLayer *barPathLayer		= [CAShapeLayer layer];
    barPathLayer.frame				= _barLayer.bounds;
    barPathLayer.bounds				= _barLayer.bounds;
    barPathLayer.geometryFlipped    = YES;
    barPathLayer.path				= path.CGPath;
    barPathLayer.strokeColor        = barColor.CGColor;//[barColor colorWithAlphaComponent:self.barAlpha].CGColor;
    barPathLayer.fillColor			= nil;
    barPathLayer.lineWidth			= fBarWid;//self.barWidth;//(_nSetUnit != 251)?self.barWidth: self.barWidth/3;
    barPathLayer.lineJoin			= kCALineJoinBevel;
    barPathLayer.hidden				= YES;
    barPathLayer.shadowOffset		= self.barShadowOffset;
    barPathLayer.shadowColor        = [UIColor clearColor].CGColor; //self.barShadowColor.CGColor;
    barPathLayer.shadowOpacity		= self.barShadowAlpha;
    barPathLayer.shadowRadius		= self.barShadowRadius;
        
    [_barLayer addSublayer:barPathLayer];
    [_barPathLayers addObject:barPathLayer];
        
      if(_nSetUnit == 251) {
        //low rate time
      UIBezierPath *lPath			= [UIBezierPath bezierPath];
      CGFloat lTime = [_dataSource barChart:self lTimeForBarAtIndex:i] * barHeightRatio;
      [lPath moveToPoint:CGPointMake(bottom.x-self.barWidth/3, bottom.y)];
      [lPath addLineToPoint:CGPointMake(bottom.x-self.barWidth/3, lTime)];
            
      CAShapeLayer *lTimeLayer		= [CAShapeLayer layer];
      lTimeLayer.frame				= _barLayer.bounds;
      lTimeLayer.bounds			= _barLayer.bounds;
      lTimeLayer.geometryFlipped   = YES;
      lTimeLayer.path				= lPath.CGPath;
      lTimeLayer.strokeColor       = [UIColor blueColor].CGColor;
      //hrateLayer.strokeColor       = [UIColor colorWithRed:0.0 green: 0.45 blue: 0.01 alpha:0.75].CGColor;
      lTimeLayer.fillColor         = nil;
      lTimeLayer.lineWidth         = self.barWidth / 3;
      lTimeLayer.lineJoin			= kCALineJoinBevel;
      lTimeLayer.hidden			= YES;
      lTimeLayer.shadowOffset		= self.barShadowOffset;
      lTimeLayer.shadowColor       = self.barShadowColor.CGColor;
      lTimeLayer.shadowOpacity     = self.barShadowAlpha;
      lTimeLayer.shadowRadius		= self.barShadowRadius;
            
      [_barLayer addSublayer:lTimeLayer];
      [_barPathLayers addObject:lTimeLayer];
            
      //high rate time
      UIBezierPath *hPath			= [UIBezierPath bezierPath];
      CGFloat hTime = [_dataSource barChart:self hTimeForBarAtIndex:i] * barHeightRatio;
      [hPath moveToPoint:CGPointMake(bottom.x+self.barWidth/3, bottom.y)];
      [hPath addLineToPoint:CGPointMake(bottom.x+self.barWidth/3, hTime)];
            
      CAShapeLayer *hTimeLayer		= [CAShapeLayer layer];
      hTimeLayer.frame				= _barLayer.bounds;
      hTimeLayer.bounds			= _barLayer.bounds;
      hTimeLayer.geometryFlipped   = YES;
      hTimeLayer.path				= hPath.CGPath;
      hTimeLayer.strokeColor       = [UIColor orangeColor].CGColor;
        //hrateLayer.strokeColor       = [UIColor colorWithRed:0.0 green: 0.45 blue: 0.01 alpha:0.75].CGColor;
      hTimeLayer.fillColor         = nil;
      hTimeLayer.lineWidth         = self.barWidth/3;
      hTimeLayer.lineJoin			= kCALineJoinBevel;
      hTimeLayer.hidden			= YES;
      hTimeLayer.shadowOffset		= self.barShadowOffset;
      hTimeLayer.shadowColor       = self.barShadowColor.CGColor;
      hTimeLayer.shadowOpacity     = self.barShadowAlpha;
      hTimeLayer.shadowRadius		= self.barShadowRadius;
        
      [_barLayer addSublayer:hTimeLayer];
      [_barPathLayers addObject:hTimeLayer];
    }
    else if(_nSetUnit == 250) { //cal burned
            
    }
        
    if(_nSetUnit == 253) {
      xPos += self.barWidth * ( _bIp6p?1.20: 1.22);
    }
    else if(_nSetUnit == 254) {
      xPos += self.barWidth * ( _bIp6p?1.20: 1.22);
    }
    else {
      xPos += _barLayer.bounds.size.width / (_numberOfBars + 1);
    }
  }
}

- (void)animateBarAtIndex:(NSInteger)index
{
    if (index >= _barPathLayers.count) {
        // Last bar, begin drawing grids
        [self displayAxisLabels];
        return;
    }
    
    if(self.hasYLabels) {
        __block NSInteger i = index + 1;
        __weak UIGraphView *weakSelf = self;
        [CATransaction begin];
        [CATransaction setAnimationDuration:(self.animationDuration / (CGFloat)_barPathLayers.count)];
        [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
        [CATransaction setCompletionBlock:^{
            [weakSelf animateBarAtIndex:i];
        }];
        
        CAShapeLayer *barPathLayer		= [_barPathLayers objectAtIndex:index];
        barPathLayer.hidden				= NO;
        [self drawBar:barPathLayer];
        
        [CATransaction commit];
    }
}

- (void)drawBar:(CAShapeLayer *)barPathLayer
{
    if (self.animationDuration == 0.0)
        return;
    
    [barPathLayer removeAllAnimations];
    
    CABasicAnimation *pathAnimation	= [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.fromValue			= [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue			= [NSNumber numberWithFloat:0.4f];
    [barPathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
}

/*- (void) drawRect:(CGRect)rect
 {
 CGContextRef context = UIGraphicsGetCurrentContext();
 _nCurtUnit = 2;
 [self setGoalWgtInfo:120 unit:2];
 //[self drawGoalsStarMark: context];
 }*/

#pragma mark curve

- (void) drawCurve
{
  if(_numberOfBars == 0)
    return;
  //cleas bar text
  _yLabelView.alpha	 = 0.0;
  _xLabelView.alpha = 0.0;
  _barTextView.alpha = 0.0;
  [[_barTextView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
  CGFloat yMinValOff = _bBldpCtrl?_minHeight.floatValue: 0.0;
    
  //remove bars
  for (CAShapeLayer *layer in _barPathLayers) {
    if (layer != nil) {
      [layer removeFromSuperlayer];
    }
  }
  [_barPathLayers removeAllObjects];
  //if(_bBldpCtrl) {
    //[self drawBldpColorBand];
  //}
    
  CGFloat barHeightRatio  = _barHeightRatio;//_barLayer.bounds.size.height / (CGFloat)_topValue;
  CGFloat barWidthRatio   = _barWidthRatio;//(_barLayer.bounds.size.width - self.incrmtxposValue * 2) / (CGFloat)_rightValue;
    
  CGFloat xOff = _fLeftMargin + _nXposOffset / (_bIpad?1.5:(_bIp6?2.2:2.5));// - self.incrmtxposValue + _gridLayer.bounds.size.width / 55.0;
  CGFloat yOff = _fBottomMargin * 1.0 + ((_nSetUnit == 253 || _nSetUnit == 254)?20.0:0.0);
  CGFloat xPos0           = ((NSNumber *)[_barHoriPos objectAtIndex:0]).floatValue * barWidthRatio + xOff;
  //CGFloat xPos            =  self.incrmtxposValue + xOff;
  CGFloat xPos            =  xPos0;
  CGFloat yPos            = (((NSNumber *)[_barHeights objectAtIndex:0]).floatValue - yMinValOff)* barHeightRatio + yOff;
  
  UIColor *curColor				= [UIColor redColor];
  if(_bBldpCtrl) {
    if(_nSetUnit == 201)
      curColor = [UIColor blueColor];
    else
      curColor = [UIColor greenColor];
  }
  else if (_dataSource && [_dataSource respondsToSelector:@selector(barChartColor)]) {
    curColor = [_dataSource barChartColor];
  }
  
  UIBezierPath *path		= [UIBezierPath bezierPath];
  //UIBezierPath *lpPath		= [UIBezierPath bezierPath];
  CGPoint top				= CGPointMake(xPos, yPos);
  [path moveToPoint:top];
  [path addArcWithCenter:top radius:3 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
   	
  for (NSInteger i = 1; i < _numberOfBars; i++)	{
    //CGPoint bottom					= CGPointMake(xPos, _barLayer.bounds.origin.y);
    //xPos = self.incrmtxposValue + ((NSNumber *)[_barHoriPos objectAtIndex:i]).floatValue * barWidthRatio + xPos0;
    xPos = ((NSNumber *)[_barHoriPos objectAtIndex:i]).floatValue * barWidthRatio + xOff;
    yPos = (((NSNumber *)[_barHeights objectAtIndex:i]).floatValue - yMinValOff) * barHeightRatio + yOff;
    top	= CGPointMake(xPos, yPos);
    //if(xPos == NaN || yPos == Nan)
    //continue;
    [path addLineToPoint:top];
    [path addArcWithCenter:top radius:3 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
  }
    
    
  CAShapeLayer *barPathLayer		= [CAShapeLayer layer];
  barPathLayer.frame				= _barLayer.bounds;
  barPathLayer.bounds				= _barLayer.bounds;
  barPathLayer.geometryFlipped    = YES;
  barPathLayer.path				= path.CGPath;
  barPathLayer.strokeColor        = curColor.CGColor;//[barColor colorWithAlphaComponent:self.barAlpha].CGColor;
  barPathLayer.fillColor			= nil;//barColor.CGColor;
  if(_bBldpCtrl)
    barPathLayer.lineWidth			= 1.5;
  else
    barPathLayer.lineWidth			= 1.25;//0.75;//1.0;//self.barWidth;
  barPathLayer.lineJoin			= kCALineJoinBevel;
  barPathLayer.hidden				= YES;
  
  [_barLayer addSublayer:barPathLayer];
  [_barPathLayers addObject:barPathLayer];
  
  if(!_bBldpCtrl) {
    top.x =  xPos + 3;
    top.y = yOff;
    [path addLineToPoint:top];
    xPos = ((NSNumber *)[_barHoriPos objectAtIndex:0]).floatValue * barWidthRatio + xOff;
    top = CGPointMake(xPos, yOff);
    [path addLineToPoint:top];
    top = CGPointMake(xPos0, ((NSNumber *)[_barHeights objectAtIndex:0]).floatValue * barHeightRatio + yOff);
    [path addLineToPoint:top];
  
    
    CAShapeLayer *fillShadow      = [CAShapeLayer layer];
    fillShadow.frame              = _barLayer.bounds;
    fillShadow.bounds             = _barLayer.bounds;
    fillShadow.geometryFlipped    = YES;
    fillShadow.path               = path.CGPath;
    fillShadow.strokeColor        = nil;
    fillShadow.fillColor          = [[UIColor orangeColor] colorWithAlphaComponent:0.125].CGColor;//[curColor colorWithAlphaComponent:self.barAlpha/5.0].CGColor;//barColor.CGColor;
    fillShadow.lineWidth          = 0.0;//self.barWidth;
    fillShadow.lineJoin           = kCALineJoinBevel;
    fillShadow.hidden             = YES;
    //fillShadow.shadowOffset		= self.barShadowOffset;
    //fillShadow.shadowColor       = self.barShadowColor.CGColor;
    //fillShadow.shadowOpacity		= self.barShadowAlpha;
    //fillShadow.shadowRadius		= self.barShadowRadius;
    //fillShadow.colors = [NSArray arrayWithObjects: (id)[UIColor grayColor].CGColor, (id)[UIColor whiteColor].CGColor,nil];
    [_barLayer addSublayer:fillShadow];
    [_barPathLayers addObject:fillShadow];
  }
    
  if(_nSetUnit == 251) {
    UIBezierPath *extPath			= [UIBezierPath bezierPath];
    //low rate
    xPos = self.incrmtxposValue + ((NSNumber *)[_barHoriPos objectAtIndex:0]).floatValue * barWidthRatio - xPos0;
    yPos = [_dataSource barChart:self lTimeForBarAtIndex:0]* barHeightRatio;
    [extPath moveToPoint:CGPointMake(xPos, yPos)];
    for (NSInteger i = 1; i < _numberOfBars; i++) {
      xPos = self.incrmtxposValue + ((NSNumber *)[_barHoriPos objectAtIndex:i]).floatValue * barWidthRatio - xPos0;
      yPos = [_dataSource barChart:self lTimeForBarAtIndex:i]* barHeightRatio;
      top	= CGPointMake(xPos, yPos);
      [extPath addLineToPoint:top];
    }
    CAShapeLayer *lTimeLayer		= [CAShapeLayer layer];
    lTimeLayer.frame				= _barLayer.bounds;
    lTimeLayer.bounds			= _barLayer.bounds;
    lTimeLayer.geometryFlipped   = YES;
    lTimeLayer.path				= extPath.CGPath;
    lTimeLayer.strokeColor       = [UIColor blueColor].CGColor;
    //hrateLayer.strokeColor       = [UIColor colorWithRed:0.0 green: 0.45 blue: 0.01 alpha:0.75].CGColor;
    lTimeLayer.fillColor         = nil;
    lTimeLayer.lineWidth         = 1;//self.barWidth;
    lTimeLayer.lineJoin			= kCALineJoinBevel;
    lTimeLayer.hidden			= YES;
    lTimeLayer.shadowOffset		= self.barShadowOffset;
    lTimeLayer.shadowColor       = self.barShadowColor.CGColor;
    lTimeLayer.shadowOpacity     = self.barShadowAlpha;
    lTimeLayer.shadowRadius		= self.barShadowRadius;
      
    [_barLayer addSublayer:lTimeLayer];
    [_barPathLayers addObject:lTimeLayer];
        
    CAShapeLayer *hTimeLayer		= [CAShapeLayer layer];
    hTimeLayer.frame				= _barLayer.bounds;
    hTimeLayer.bounds			= _barLayer.bounds;
    hTimeLayer.geometryFlipped   = YES;
    hTimeLayer.path				= extPath.CGPath;
    hTimeLayer.strokeColor       = [UIColor orangeColor].CGColor;
    //hrateLayer.strokeColor       = [UIColor colorWithRed:0.0 green: 0.45 blue: 0.01 alpha:0.75].CGColor;
    hTimeLayer.fillColor         = nil;
    hTimeLayer.lineWidth         = 1;//self.barWidth;
    hTimeLayer.lineJoin			= kCALineJoinBevel;
    hTimeLayer.hidden			= YES;
    hTimeLayer.shadowOffset		= self.barShadowOffset;
    hTimeLayer.shadowColor       = self.barShadowColor.CGColor;
    hTimeLayer.shadowOpacity     = self.barShadowAlpha;
    hTimeLayer.shadowRadius		= self.barShadowRadius;
      
    [_barLayer addSublayer:hTimeLayer];
    [_barPathLayers addObject:hTimeLayer];
  }
  else if(_nSetUnit == 250) { //cal burned
        
  }
}

#pragma goals mark

- (void)setGoalWgtInfo:(float)dWgtVal unit:(short)nUnit
{
    _goalWgt = dWgtVal;
    _wgtUnit = nUnit;
}

- (void) setCaloriyUnit:(NSInteger)nIdx
{
    if(_nSetUnit != 250)
        return;
    
    if(nIdx == 0)
        _lblMeasUnit.text = NSLocalizedString(@"calory", nil);
    else
        _lblMeasUnit.text = NSLocalizedString(@"kcalory", nil);
}

//drawing background img
- (void)renderBkgdImage:(CGContextRef)ctx
{
    //CGSize size = self.frame.size;
    UIGraphicsPushContext(ctx);
    //UIImage* imgBkgd = [UIImage imageNamed:@"Ac-Home.png"];
    UIImage* imgBkgd = [UIImage imageNamed:@"ic_gridbkgd_s.png"];
    
    //CGContextTranslateCTM(ctx, 0, -imgBkgd.size.height);
    //CGContextScaleCTM(ctx, 1.0, -1.0);
    //CGContextDrawImage(ctx, CGRectMake(30, 1, imgBkgd.size.width, imgBkgd.size.height), imgBkgd.CGImage);
    
    //CGContextDrawImage(ctx, self.bounds, imgBkgd.CGImage);
    //[imgBkgd drawInRect:CGRectMake(28, 1, imgBkgd.size.width, imgBkgd.size.height)];
    [imgBkgd drawInRect:_borderLayer.bounds];
    UIGraphicsPopContext();
    
    /*UIGraphicsBeginImageContext(size);
     [imgBkgd drawInRect:CGRectMake(0.0, 0.0, size.width/5, size.height/5)];
     //Draw your lines here
     UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     return newImage;*/
}

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
{
  if(_bBldpCtrl) {
    [self drawBldpColorBand:ctx];
  }
  
  if(_nSetUnit != 253 && _nSetUnit != 254)
    return;
    
    CGContextSetFillColorWithColor(ctx, [UIColor clearColor].CGColor);
    CGContextFillRect(ctx, layer.bounds);
    
    float fGoalVal = _goalWgt;
    if(_nSetUnit == 253) {
        fGoalVal = [self.dataSource goalSteps];;
    }
    else if(_nSetUnit == 254) {
        fGoalVal = [self.dataSource goalDists];
    }
    else if(_nSetUnit != _wgtUnit) {
        if(_nSetUnit == 2)
            fGoalVal *= _KgtoLb;
        else
            fGoalVal /= _KgtoLb;
    }
    
    CGContextSetStrokeColorWithColor(ctx, [UIColor colorWithRed:0.00 green:0.53 blue:0.28 alpha:1.00].CGColor);
    CGContextSetLineWidth(ctx, 1.25);
    CGContextBeginPath(ctx);
    //CGContextSetLineDash(ctx, 0, lengths,2);
  CGFloat yPos = _gridLayer.bounds.size.height - fGoalVal * _barHeightRatio - _fBottomMargin;// + _fTopMargin;
    
    CGFloat r = 4.0;
    float xCenter = 32 - (_bIpad? 0: _bIp6? 10: 15);//self.frame.size.width + 5;
    float yCenter = yPos;
    
    // draw goal mark [pathGoal moveToPoint:CGPointMake(xCenter, yCenter - r)];
    CGContextMoveToPoint(ctx, xCenter, yCenter - r);
    for(int i = 1; i < 6; ++i) {
        CGFloat x = r * sinf(i * 4.0 * M_PI / 5.0);
        CGFloat y = r * cosf(i * 4.0 * M_PI / 5.0);
        //[pathGoal addLineToPoint:CGPointMake(xCenter - x, yCenter - y)];
        CGContextAddLineToPoint(ctx, xCenter - x, yCenter - y);
    }
    //UIColor *barColor				= [UIColor orangeColor];
    //if (_dataSource && [_dataSource respondsToSelector:@selector(barChart:colorForBarAtIndex:)])
    //barColor = [_dataSource barChart:self colorForBarAtIndex:i];
    
    /*_goalPathLayer     = [CAShapeLayer layer];
     _goalPathLayer.frame             = _barLayer.bounds;
     _goalPathLayer.bounds            = _barLayer.bounds;
     _goalPathLayer.geometryFlipped   = YES;
     _goalPathLayer.path              = pathGoal.CGPath;
     _goalPathLayer.strokeColor      = barColor.CGColor;
     _goalPathLayer.fillColor        = nil;
     _goalPathLayer.lineWidth        = 1.5f;
     _goalPathLayer.lineJoin         = kCALineJoinBevel;
     
     //_goalPathLayer.zPosition = 999;
     [_barLayer addSublayer:_goalPathLayer];
     //[_borderLayer addSublayer:_goalPathLayer];*/
    CGContextStrokePath(ctx);
    //CGContextEndPage(ctx);
    
    CGContextSetLineWidth(ctx, 0.75);
    CGContextBeginPath(ctx);
    CGFloat lengths[] = {2, 1};
    CGContextSetLineDash(ctx, 0, lengths, 2);
    CGContextMoveToPoint(ctx, xCenter+10, yCenter);
    CGContextAddLineToPoint(ctx, xCenter + self.frame.size.width - 10, yCenter);
    CGContextStrokePath(ctx);
    
    //draw text
    //static char sTxt[6] = "Goal";
    NSString* sTxt = @"Goal";
    CGContextSetRGBFillColor(ctx, 0.90, 0.5, 0.1, 1);
    CGContextSetTextDrawingMode(ctx, kCGTextFill);
    //CGContextSelectFont(ctx, "Helvetica", 10, kCGEncodingMacRoman); //Arial
    CGAffineTransform transform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
    CGContextSetTextMatrix(ctx, transform);
    
    //CGContextShowTextAtPoint(ctx, xCenter-5, yCenter-8, sTxt, strlen(sTxt));
    [ self drawAtPoint:CGPointMake(xCenter, yCenter-8) withStr:sTxt color:[UIColor whiteColor] font:13];
}

- (void)animateGoalMark:(NSInteger)index
{
    /*if (index >= _barPathLayers.count) {
     // Last bar, begin drawing grids
     [self displayAxisLabels];
     return;
     }
     
     __block NSInteger i = index + 1;
     __weak GraphView *weakSelf = self;
     [CATransaction begin];
     [CATransaction setAnimationDuration:(self.animationDuration / (CGFloat)_barPathLayers.count)];
     [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
     [CATransaction setCompletionBlock:^{
     [weakSelf animateBarAtIndex:i];
     }];
     
     CAShapeLayer *barPathLayer		= [_barPathLayers objectAtIndex:index];
     barPathLayer.hidden				= NO;
     [self drawBar:barPathLayer];
     
     [CATransaction commit];*/
}

#pragma mark Grid

- (void)setupGrid
{
  //return;
  
  if (_gridPathLayer != nil) {
    [_gridPathLayer removeFromSuperlayer];
    _gridPathLayer = nil;
  }
  if (_gridPathLayer_x != nil) {
    [_gridPathLayer_x removeFromSuperlayer];
    _gridPathLayer_x = nil;
  }
  if(_xShowLabelPoints != nil) {
    [_xShowLabelPoints removeAllObjects];
  }
    
  CGFloat gridUnit		= _barHeightRatio;
  //CGFloat gridUnit		= _gridLayer.bounds.size.height / _topValue;
  CGFloat gridSeperation	= gridUnit * (CGFloat)self.incrementValue;
  if(_nSetUnit == 251 && _maxHeight.floatValue <= 1 && self.incrementValue == 1) {
    gridSeperation = gridSeperation / 4;
  }
  else if(_nSetUnit == 250) { //cal burned
    gridSeperation = gridSeperation;
  }
  //else if(_nSetUnit <= _nWgtLimitIdx) {
    //gridSeperation -= gridSeperation / 8.0;
  //®}
    
  CGFloat	xPos      = 0.0;
  CGFloat yPos			= 0.0;
  CGFloat xOff = _fLeftMargin - _nXposOffset / (_bIpad?1.0: _bIp6p?-4.0:(_bIp6?-4.5: -6.0));// + 12
  if(_nSetUnit != 253 && _nSetUnit != 254) {
    xPos = _fLeftMargin;
    yPos			= _fBottomMargin + gridSeperation;
    //if(_nSetUnit <= _nWgtLimitIdx && _bIp6p) {
      //yPos -= 5;
    //}
   
    CGFloat yTop            = _gridLayer.bounds.size.height - _fTopMargin + 0.5;
    UIBezierPath *path		= [UIBezierPath bezierPath];
    while (yPos < yTop) { //Y dirction
      xPos = _fLeftMargin + (_bIpad?0: _bIp5?1:(_bIp4s?2:0));
      CGPoint left	= CGPointMake(xPos, yPos);
      CGPoint right	= CGPointMake(xPos + _gridLayer.bounds.size.width / (_bIpad?60.0:50.0), yPos);
        
      [path moveToPoint:left];
      [path addLineToPoint:right];
        
      yPos += gridSeperation + 0;
    }
    
    _gridPathLayer                  = [CAShapeLayer layer];
    _gridPathLayer.frame            = _gridLayer.bounds;
    _gridPathLayer.bounds           = _gridLayer.bounds;
    _gridPathLayer.geometryFlipped  = YES;
    _gridPathLayer.path             = path.CGPath;
    _gridPathLayer.strokeColor      = self.gridColor.CGColor;
    _gridPathLayer.fillColor        = nil;
    _gridPathLayer.lineWidth        = 0.35f;
    _gridPathLayer.lineJoin         = kCALineJoinBevel;
    [_gridLayer addSublayer:_gridPathLayer];
  }
  else {
    if(_bIpad)
      xOff += _fLeftMargin +  (self.barWidth * ((_nSetUnit == 254)?0.15:0.03));
    else
      xOff += _fLeftMargin +  (self.barWidth * ((_nSetUnit == 254)?0.30:0));
  }
  
  if (_barLabels.count == 0)
    return;
  
  //yPos -= _gridLayer_x.bounds.size.height * (_bIpad?0.9:(_bIp6?0.6:(_bHgter?0.25:(_bIp4s?-0.1:0.2))));
  yPos -= (_fBottomMargin  + _gridLayer_x.bounds.size.height) * (_bIpad?0.36:_bIp6p?0.58:(_bIp6?0.47:(_bIp5?0.37:0.25)));
  
  //adjust
  if(_nSetUnit == 202) { //bldp hval
    //CGFloat y1 = _fBottomMargin;
    //CGFloat y2 =  _gridLayer_x.bounds.size.height;
    yPos -= (_fBottomMargin + _gridLayer_x.bounds.size.height) * (_bIpad?0.30:_bIp6p?0.42:_bIp6?0.39:_bIp5?0.28:0.22);
    //if(!_bIpad)
      //yPos += (_nSetUnit == 202)? -10.0: 0.0;
  }
  else if(_nSetUnit == 253 || _nSetUnit == 254) {
    yPos = self.frame.size.height -_fBottomMargin  + _fTopMargin * (_bIpad?2.9:2.8);
  }
  else if(!_bBldpCtrl) {
    yPos -= (_fBottomMargin + _gridLayer_x.bounds.size.height) * (_bIpad?0.10:_bIp6p?0.100:_bIp6?0.095:_bIp5?0.002:0.001);
    if(_nSetUnit == _nWgtLimitIdx)
       yPos -= (_bIpad?84:_bIp6p?53:_bIp6?47:_bIp5?33:27);
  }
  UIBezierPath *xPath		= [UIBezierPath bezierPath];
    
  CGFloat barWidthRatio = _barWidthRatio;
  
  if(_bDrawCurve ) {
    xOff += _nXposOffset * 0.75;
  }
  
  xPos = xOff;
  CGFloat	xPos0 = xPos;
  if(_bDrawCurve) {
    xOff += _fLeftMargin / (_bIpad?3.2: _bIp6p?4.0: (_bIp6?3.0:_bIp5?3.5:3.5));
    if(_nSetUnit <= _nWgtLimitIdx)
      xOff -=  _bIpad?1.0:_bIp6p?-11.0: (_bIp6?-2.5:_bIp5?2.2:2.0);
    xPos0  = ((NSNumber *)[_barHoriPos objectAtIndex:0]).floatValue * barWidthRatio + xOff;
    xPos = xPos0;
  }
  else if(_nSetUnit == 253 || _nSetUnit == 254) {
    xPos += _bIpad? (_nLeftMargin * 3.0 / 3.2): 0.0;
  }
    
  //CGFloat xPosInit = xPos;
  CGFloat xPosLast = self.incrmtxposValue; //xPos0;
  NSInteger nStart = _bDrawCurve? 1: 0;
  [_xShowLabelPoints addObject:[NSNumber numberWithInteger:0]];
  
  if(_nSetUnit <= _nWgtLimitIdx) {
    yPos += _bIp6p?3:_bIp6?2.0:0;
    if(_nSetUnit == _nWgtLimitIdx)
      yPos += 1.5;
  }
  
  for (NSInteger i = nStart; i < _numberOfBars; i++) {
    if(_bDrawCurve) {
      xPos = ((NSNumber *)[_barHoriPos objectAtIndex:i]).floatValue * barWidthRatio + xOff;
      if(_bBldpCtrl)
         xPos += _bIpad?10:_bIp6p?-5:_bIp6?-4:-2;
      else
        xPos += _bIpad?10:_bIp6p?-15:_bIp6?-5:_bIp5?-1:-1;
      if(xPos-xPosLast < self.barWidth)
        continue;
    }
    else {
      xPos += _barLayer.bounds.size.width / (_numberOfBars + 1);
    }
        
    CGPoint one	= CGPointMake(xPos, yPos);
    CGPoint two	= CGPointMake(xPos, yPos + _gridLayer.bounds.size.height / (_bIpad?40.0: 35.0));
    [xPath moveToPoint:one];
    [xPath addLineToPoint:two];
    
    if(_bDrawCurve)
      xPosLast = xPos;
    [_xShowLabelPoints addObject:[NSNumber numberWithInteger:i]];
    
    if(_nSetUnit == 253) {
      xPos += 3;
    }
    else if(_nSetUnit == 254) {
      xPos += 1;
    }
  }
    
  _gridPathLayer_x                  = [CAShapeLayer layer];
  _gridPathLayer_x.frame            = _gridLayer.bounds;
  _gridPathLayer_x.bounds           = _gridLayer.bounds;
  _gridPathLayer_x.geometryFlipped  = YES;
  _gridPathLayer_x.path             = xPath.CGPath;
  _gridPathLayer_x.strokeColor      = self.gridColor.CGColor;
  _gridPathLayer_x.fillColor        = nil;
  _gridPathLayer_x.lineWidth        = 0.35f;
  _gridPathLayer_x.lineJoin         = kCALineJoinBevel;
  
  [_gridLayer_x addSublayer:_gridPathLayer_x];
  //[_barPathLayers addObject:_gridPathLayer_x];
    
}

- (void)drawGrid
{
  if (self.animationDuration == 0.0)
    return;
    
  [_borderLayer removeAllAnimations];
    
  CABasicAnimation *pathAnimation	= [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  pathAnimation.duration			= self.animationDuration;
  pathAnimation.fromValue			= [NSNumber numberWithFloat:0.0f];
  pathAnimation.toValue			= [NSNumber numberWithFloat:0.4f];
  pathAnimation.timingFunction	= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  [_gridPathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
}

#pragma mark Axis Labels

- (void)setupYAxisLabels:(UIColor *)lColor
{
  //return;
  BOOL bBldp = _nSetUnit == 201 || _nSetUnit == 202;
  if (!self.hasYLabels || _nSetUnit == 253 || _nSetUnit == 254)
    return;
    
  NSUInteger n = [_yLabelView subviews].count;
  //if (_yLabelView.alpha > 0.0) {
  if( n > 0) {
    _yLabelView.alpha = 0.0;
    [[_yLabelView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
  }
    
  //CGFloat gridUnit			= _gridLayer.bounds.size.height / _topValue;
  CGFloat gridUnit             = _barHeightRatio;
  CGFloat gridSeperation		= gridUnit * (CGFloat)self.incrementValue;
    
  //CGSize yLabelSize			= [[NSString stringWithFormat:@"%i", (int)_topValue] sizeWithFont:self.yLabelFont];
  CGSize yLabelSize			= [[NSString stringWithFormat:@"%i", (int)_topValue] sizeWithAttributes:@{NSFontAttributeName: self.yLabelFont}];
  CGFloat yPos				= 0.0;
  NSInteger maxVal			= _topValue;
  NSInteger minVal = bBldp?_minHeight.integerValue:0;
  NSInteger botVal = _gridLayer.bounds.size.height;
  
  while (maxVal >= minVal && yPos < botVal) {
    CGRect yLabelFrame		= CGRectMake(0.0, 0.0, yLabelSize.width, yLabelSize.height);
    UILabel *yLabel			= [[UILabel alloc] initWithFrame:yLabelFrame];
    yLabel.font				= self.yLabelFont;
    yLabel.backgroundColor	= [UIColor clearColor];
      if (lColor == nil) {
          yLabel.textColor		= [UIColor grayColor];//self.yLabelColor;
      } else {
          yLabel.textColor		= lColor;//self.yLabelColor;
      }
    
    yLabel.textAlignment	= NSTextAlignmentRight;
    yLabel.center			= CGPointMake(yLabel.center.x + _fLeftMargin, yPos +  _fTopMargin);
    
    yLabel.text				= [NSString stringWithFormat:@"%i", (int)maxVal];
    [_yLabelView addSubview:yLabel];
    maxVal					-= self.incrementValue;
    yPos					+= gridSeperation;
    
    //if(_bBldpCtrl)
      //maxVal -= 30;
  }
 
  if(_numberOfBars == 0)
    _yLabelView.alpha = 1.0;
}

- (NSInteger) getStoredXPoints:(NSInteger)nIdx
{
    NSInteger n = -1;
    NSInteger nCount = _xShowLabelPoints.count;
    for(NSInteger i=0; i<nCount; i++) {
        NSNumber* obj = [_xShowLabelPoints objectAtIndex:i];
        NSInteger m = obj.integerValue;
        if(m == nIdx) {
            n = m;
            break;
        }
    }
    return n;
}

- (CGFloat) getXposOffset: (Byte)nType xinitOff:(CGFloat) fxOffset
{
  CGFloat xOffset = 0;
  BOOL bIos9 = [[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0;
  BOOL bChinaLng = [AppDelegate isLanguageChines];
  if(_nSetUnit == 253) {
    xOffset = self.frame.size.width / (_numberOfBars + 1) - self.barWidth * (_bIpad? 0.14: 0.0);
    if(!bIos9 && _bIp6p && !bChinaLng)
      xOffset += 2;
    else if(bIos9)
      xOffset += 0.4;
  }
  else if(_nSetUnit == 254) {
    xOffset = self.frame.size.width / (_numberOfBars + 1) - self.barWidth * 0.375;
    if(bIos9)
      xOffset += 1.25;
  }
  else {
    xOffset = _barLayer.bounds.size.width / (_numberOfBars + 1) + fxOffset;
  }
  
  return xOffset;
}

- (void)setupXAxisLabels:(UIColor *)xColor
{
  if(_numberOfBars == 0)
    return;
  _xLabelView.alpha = 0.0;
  [[_xLabelView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
  if (_barLabels.count == 0 && _nSetUnit != 253 && _nSetUnit !=254)
    return;
    
  CGFloat xOff = _fLeftMargin + _nXposOffset / (_bIpad?1.5:2.0) + 10;
  
  CGFloat barWidthRatio = 0;
  CGFloat	xPos = self.incrmtxposValue + _fLeftMargin + _nXposOffset + self.barWidth * (_bIpad?0.68:_bIp6p?0.21:(_bIp6?0.21:(_bIp4s?-0.12:-0.15))); //* (_bIpad?1.5:2.2);
  if(_nSetUnit == 253 || _nSetUnit == 254) {
    BOOL bLangCHines = [AppDelegate isLanguageChines];
    CGFloat fEngIp6pOffRate = -0.1;
    if(_bIp6p)
      xPos += self.barWidth * (_bIpad? 0.50: (_nSetUnit == 254)?(bLangCHines?0.1:fEngIp6pOffRate): 0.0);
    else
      xPos += self.barWidth * (_bIpad? 0.50: (_nSetUnit == 254)?0.1: 0.0);
  }
   
  if(_bIpad) {
    if(_numberOfBars == 7)
      xPos -= self.barWidth * 0.25;
    else if(_numberOfBars == 6)
      xPos -= self.barWidth * 0.05;
    else if(_numberOfBars == 5)
      xPos += self.barWidth * 0.20;
    else if(_numberOfBars == 4)
      xPos += self.barWidth * 0.50;
    else if(_numberOfBars == 3)
      xPos += self.barWidth * 1.00;
    else if(_numberOfBars == 2)
      xPos += self.barWidth * 1.80;
    else if(_numberOfBars == 1)
      xPos += self.barWidth * 3.35;
  }
  else {
    CGFloat fDiv = 2.5;
    switch (_numberOfBars) {
      case 1:
        fDiv = _bIp6?1.92:1.75;
        break;
      case 2:
        fDiv = _bIp6?2.9:2.6;
        break;
      case 3:
        fDiv = _bIp6?3.6:3.2;
        break;
      case 4:
        fDiv = _bIp6?4.5:3.7;
        break;
      case 5:
        fDiv = _bIp6?5.4:4.2;
        break;
      case 6:
        fDiv = _bIp6?10.1:4.5;
        break;
                
      default:
        fDiv =1.0;
    }
    //xPos += self.barWidth * (_nSwitchCount - _numberOfBars) / fDiv;
    xPos += self.barWidth * (7 - _numberOfBars) / fDiv;
  }
  CGFloat	xPos0 = xPos;
  if(_bDrawCurve) {
    barWidthRatio	= _barWidthRatio;
    xOff = _fLeftMargin + _nXposOffset / (_bIpad?1.2:_bIp6p?1.6:2.0);
    //xOff -= _fLeftMargin / (_bIpad?6.0:3.0);
    xPos0           = ((NSNumber *)[_barHoriPos objectAtIndex:0]).floatValue * barWidthRatio + xOff;
    xPos = xPos0;
  }
    
  //CGFloat xPosInit = xPos;
  CGFloat xPosLast = self.incrmtxposValue;
  CGFloat fxOffset = (_nSetUnit == 253 || _nSetUnit == 254)? (_bIpad?8.5: 3.5):(_nSetUnit <= _nWgtLimitIdx)?4.0:-3.0;
  CGFloat fyOffset = 0; //(_nSetUnit == 253 || _nSetUnit == 254)? 20.0:(_nSetUnit <= _nWgtLimitIdx)?24.0:0.0;
  
  if(_bIpad) {
    if(_bBldpCtrl) {
      xPos += _bDrawCurve? 5: -4;
      fxOffset += _bDrawCurve?-5:3;
      fyOffset += _bDrawCurve?1:25;
    }
    else if(_nSetUnit <= _nWgtLimitIdx) {
      xPos += _bDrawCurve? +2: -4;
      fxOffset += _bDrawCurve?+5:-2;
      fyOffset += _bDrawCurve?5:20;
      xOff += _bDrawCurve?5:0;
    }
  }
  else if(_bIp6p) {
    if(_bBldpCtrl) {
      xPos += _bDrawCurve? 5: -4;
      fxOffset += _bDrawCurve?2:4;
      fyOffset += _bDrawCurve?6:15;
    }
    else if(_nSetUnit <= _nWgtLimitIdx) {
      xPos += _bDrawCurve? -6: -3;
      fxOffset += _bDrawCurve?-24:-3;
      fyOffset += _bDrawCurve?6:14;
    }
  }
  else if(_bIp6) {
    if(_bBldpCtrl) {
      xPos += _bDrawCurve? 5: -4;
      fxOffset += _bDrawCurve?1:3;
      fyOffset += _bDrawCurve?5:14;
    }
    else if(_nSetUnit <= _nWgtLimitIdx) {
      xPos += _bDrawCurve? 8: 2;
      fxOffset += _bDrawCurve?24:-1;
      fyOffset += _bDrawCurve?6:13;
    }
    if(_nSetUnit == _nWgtLimitIdx) {
      fxOffset -= 4;
      fyOffset += _bDrawCurve?0: 2;
    }
  }
  else if(_bIp5) {
    if(_bBldpCtrl) {
      xPos += _bDrawCurve? 5: -4;
      fxOffset += _bDrawCurve?3:4;
      fyOffset += _bDrawCurve?2:15;
    }
    else if(_nSetUnit <= _nWgtLimitIdx) {
      xPos += _bDrawCurve?8: -5;
      fxOffset += _bDrawCurve?3:-1;
      fyOffset += _bDrawCurve?2:15;
    }  }
  else if(_bIp4s) {
    if(_bBldpCtrl) {
      xPos += _bDrawCurve? 5: -4;
      fxOffset += _bDrawCurve?10: 5;
      fyOffset += _bDrawCurve?2:12;
    }
    else if(_nSetUnit <= _nWgtLimitIdx) {
      xPos += _bDrawCurve?12:-2;
      fxOffset += _bDrawCurve?16:-2;
      fyOffset += _bDrawCurve?2:12;
    }
    if(_nSetUnit == _nWgtLimitIdx) {
      fxOffset -= 2;
    }
  }
  
  if(_nSetUnit == 253 || _nSetUnit == 254)
    fyOffset += _bIpad? 25: _bIp6p? 15: _bIp6?13: 10;
  
  
  for (NSInteger i = 0; i < _numberOfBars; i++) {
    if(_bDrawCurve) {
      if(i > 0) {
        xPos = ((NSNumber *)[_barHoriPos objectAtIndex:i]).floatValue * barWidthRatio + xOff;
        if(_bBldpCtrl)
          xPos += _bIpad?-5:_bIp6p?-2:_bIp6?0:0;
        else
          xPos += _bIpad?-7:_bIp6p?0:_bIp6?3:_bIp5?-2:+1;
        BOOL bTooClose = xPos - xPosLast < _xTextSpace;
        NSInteger nIdx = [self getStoredXPoints:i];
        if(nIdx != i || bTooClose)
          continue;
      }
      else {
        xPos -= (_bIpad?18:_bIp6p?8:_bIp6?6:0);
      }
      xPosLast = xPos;
    }
    else if(_nSetUnit == 253) {
      xPos += self.barWidth * (_bIpad?0.15:0.0);
      if(_bIpad) {
        bool bNoData = YES;;
        for(int i = 0; i<7; i++) {
          if(((NSNumber*)[_barHeights objectAtIndex:i]).floatValue > 0) {
            bNoData = NO;
            break;
          }
        }
      
        if(bNoData)
          xPos += 1.5;
      }
    }
    else if(_nSetUnit == 254) {
      xPos += self.barWidth * 0.36;
    }
    
    NSString *xLabelText	= [_barLabels objectAtIndex:i];
    //CGSize xLabelSize = [xLabelText sizeWithFont:self.xLabelFont];
    CGSize xLabelSize = [xLabelText sizeWithAttributes:@{NSFontAttributeName: self.yLabelFont}];
    CGRect xLabelFrame		= CGRectMake(0, 0, xLabelSize.width + 5, xLabelSize.height);
    UILabel *xLabel			= [[UILabel alloc] initWithFrame:xLabelFrame];
    //xLabel.font				= _bDrawCurve?[UIFont fontWithName:@"Helvetica" size:(_bIp4s?8:_bIp5?9.5:10.0)]: self.xLabelFont;
    xLabel.font				= /*_bDrawCurve?self.xLabelFont :*/[UIFont systemFontOfSize:(_bIp4s?8:_bIp5?8.5:10.0)];
    xLabel.backgroundColor	= [UIColor clearColor];
      if (xColor == nil) {
        xLabel.textColor		= [UIColor grayColor];//self.xLabelColor;
      } else {
        xLabel.textColor		= xColor;//self.xLabelColor;
      }
    
    xLabel.textAlignment	= _bDrawCurve?NSTextAlignmentLeft: NSTextAlignmentCenter; //NSTextAlignmentRight;
    xLabel.text				= xLabelText;
    xLabel.transform		= CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-_xLabelRotation));
    
    // Position the label appropriately
    /*if(_nSetUnit <= _nWgtLimitIdx) {
      fyOffset -= _bDrawCurve?20:8;
      xPos -= _bIpad?-3:_bDrawCurve?1:5;
    }*/
    //fyOffset += _bIpad?10.0: 0.0;
    
    switch (self.xLabelType) {
      case GraphViewXLabelTypeVerticle:
      default:
        xLabel.center = CGPointMake(xPos, (xLabelSize.width / 2.0));
        break;
                
      case GraphViewXLabelTypeHorizontal:
        if(_bDrawCurve) {
          xLabel.center = CGPointMake(xPos, _xLabelMaxHeight / 2.0 - _nBottomMargin/ (_bIpad?1.5:3.5) + (_bBldpCtrl?8:8) + fyOffset);
          //xLabel.center = CGPointMake(self.frame.size.width-50, _xLabelMaxHeight / 2.0 - _nBottomMargin/ (_bIpad?1.5:3.5));    
        }
        else {
          xLabel.center = CGPointMake(xPos, _xLabelMaxHeight / 2.0 - _nBottomMargin / (_bIpad?1.0:2.5) + fyOffset);
        }
        break;
                
      case GraphViewXLabelTypeAngled: {
        CGFloat labelHeightWithAngle	= sin(DEGREES_TO_RADIANS(_xLabelRotation)) * xLabelSize.width;
        xLabel.center					= CGPointMake(xPos - (labelHeightWithAngle / 2.0), labelHeightWithAngle / 2.0);
        break;
      }
    }
    [_xLabelView addSubview:xLabel];
        
    if(!_bDrawCurve) {
      /*BOOL bIos9 = [[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0;
      BOOL bChinaLng = [AppDelegate isLanguageChines];
      if(_nSetUnit == 253) {
        xPos += self.frame.size.width / (_numberOfBars + 1) - self.barWidth * (_bIpad? 0.14: 0.0);
        if(!bIos9 && _bIp6p && !bChinaLng)
          xPos += 2;
        //else if(bIos9)
          //xPos += 1.5;
      }
      else if(_nSetUnit == 254) {
        xPos += self.frame.size.width / (_numberOfBars + 1) - self.barWidth * 0.375;
        if(bIos9)
          xPos += 0.5;
      }
      else {
        xPos += _barLayer.bounds.size.width / (_numberOfBars + 1) + fxOffset;
      }*/
      xPos += [self getXposOffset:1 xinitOff:fxOffset];
    }
  }
}

- (void)setupBarTexts
{
  if (_barTexts.count == 0 || _barTextView.alpha > 0.0)	{
    _barTextView.alpha = 0.0;
    for (UIView *view in [_barTextView subviews]) {
      [view removeFromSuperview];
    }
    [[_barTextView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
  }
  if (_topValue == 0 && _nSetUnit !=  253 && _nSetUnit !=254)
    return;
  
  CGFloat yPos = 0.0;
  CGFloat	xPos				= _barLayer.bounds.size.width / (_numberOfBars + 1) + _fLeftMargin - _nXposOffset * (_bIpad?1.5:0.5);
  if(_nSetUnit == 253 || _nSetUnit == 254) {
    xPos += _nLeftMargin * (_bIpad?1.2:(_nSetUnit == 254)?0.27:0.04);
  }
  CGFloat xRtPos = 1.0, yRtPos = 0;
  for (NSInteger i = 0; i < _numberOfBars; i++)	{
    if(((NSNumber*)[_barHeights objectAtIndex:i]).floatValue == 0) {
      if(_nSetUnit == 253)
        xPos += self.barWidth * (_bIpad?1.20:1.23);
      else if(_nSetUnit == 254)
        xPos += self.barWidth * 1.22;
      else
        xPos += _barLayer.bounds.size.width / (_numberOfBars + 1);
      continue;
    }
    NSString* barLabelText	= [_barTexts objectAtIndex:i];
    
    //continue;
    //CGSize barTextSize		= [barLabelText sizeWithFont:self.barTextFont];
    CGSize barTextSize		= [barLabelText sizeWithAttributes:@{NSFontAttributeName:self.barTextFont}];
    CGFloat fRtWid = barTextSize.width+3;
    CGFloat fRtHgt = barTextSize.height;

    if(_nSetUnit == 253 || _nSetUnit == 254) {
      fRtWid *= 2.5;
      fRtHgt *= 2.2;
    }
    CGRect barTextFrame     = CGRectMake(xRtPos, yRtPos, fRtWid, fRtHgt);
    UILabel *barText        = [[UILabel alloc] initWithFrame:barTextFrame];
    barText.font            = self.barTextFont;
    barText.backgroundColor	= [UIColor clearColor];
    //barText.textColor     = (_nSetUnit != 251)? self.barTextColor:[UIColor whiteColor];
    barText.textColor       = (_nSetUnit != 251)? [UIColor whiteColor]:[UIColor whiteColor];
    barText.textAlignment   = NSTextAlignmentCenter;
    barText.text            = barLabelText;

    
    CGFloat barHeight		= (_barLayer.bounds.size.height / (CGFloat)_topValue) * ((NSNumber *)[_barHeights objectAtIndex:i]).floatValue;
    yPos = ((NSNumber *)[_barHeights objectAtIndex:i]).floatValue * _barHeightRatio + _fBottomMargin;
    if(_nSetUnit == 201 || _nSetUnit == 202) {
      yPos -= _minHeight.shortValue * _barHeightRatio;
    }
    
    if(yPos >=  _barLayer.bounds.size.height) {
      yPos = _barLayer.bounds.size.height - _nTopMargin;
    }
    
    // Position the label appropriately
    switch (self.barTextType) {
      case GraphViewBarTextTypeTop:
      default:
        barText.center = CGPointMake(xPos+1, _barLayer.bounds.size.height - yPos + barTextSize.height / 2.0);
        break;
                
      case GraphViewBarTextTypeRoof:
        barText.center = CGPointMake(xPos+1, _barLayer.bounds.size.height - (barHeight + (barTextSize.height / 2.0)));
        break;
                
      case GraphViewBarTextTypeMiddle:
      {
        CGFloat minBarHeight	= (_barLayer.bounds.size.height / (CGFloat)_topValue) * _minHeight.floatValue;
        barText.center			= CGPointMake(xPos+1, _barLayer.bounds.size.height - (minBarHeight / 2.0));
        break;
      }
    }
        
    if(_nSetUnit == 253) {
      NSString* sInfo = barText.text;
      long nSteps = sInfo.integerValue;
      if(sInfo != nil) {
        barText.lineBreakMode = NSLineBreakByWordWrapping;
        barText.numberOfLines = 2;
        if(nSteps >  1000)
          sInfo = [NSString stringWithFormat:@"%ld\n %@", nSteps/1000, @"THS"];
        else
          sInfo = [sInfo stringByAppendingString:@"\nStp"];
        barText.text = sInfo;
      }
    }
    else if(_nSetUnit == 254) {
      NSString* sInfo = barText.text;
      if(sInfo != nil) {
        barText.lineBreakMode = NSLineBreakByWordWrapping;
        barText.numberOfLines = 2;
        sInfo = [sInfo stringByAppendingString:@"\nMis"];
        barText.text = sInfo;
      }
    }
    [_barTextView addSubview:barText];
    
    if(_nSetUnit == 253)
      xPos += self.barWidth * (_bIpad?1.20:1.23);
    else if(_nSetUnit == 254)
      xPos += self.barWidth * 1.22;
    else
      xPos += _barLayer.bounds.size.width / (_numberOfBars + 1);
  }
}

- (void)displayAxisLabels
{
    if (self.hasYLabels || _barTexts.count > 0 || _barLabels.count > 0)	{
        if (self.animationDuration > 0.0) {
            __weak UIGraphView *weakSelf = self;
            [UIView animateWithDuration:self.animationDuration / 2.0 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                _yLabelView.alpha	= 1.0;
                _xLabelView.alpha	= 1.0;
                _barTextView.alpha	= 1.0;
            } completion:^(BOOL finished) {
                if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(animationDidEndForBarChart:)])
                    [weakSelf.delegate animationDidEndForBarChart:weakSelf];
            }];
        }
        else {
            _yLabelView.alpha	= 1.0;
            _xLabelView.alpha	= 1.0;
            _barTextView.alpha	= 1.0;
            
            if (_delegate && [_delegate respondsToSelector:@selector(animationDidEndForBarChart:)])
                [_delegate animationDidEndForBarChart:self];
        }
    }
    else {
        if (_delegate && [_delegate respondsToSelector:@selector(animationDidEndForBarChart:)])
            [_delegate animationDidEndForBarChart:self];
    }
}

- (void) drawAtPoint:(CGPoint)point withStr:(NSString *)str color:(UIColor*)col font:(CGFloat)fSize
{
    NSDictionary *attrsDic = @{NSFontAttributeName: [UIFont systemFontOfSize:fSize], NSForegroundColorAttributeName:col};
    [str drawAtPoint:point withAttributes:attrsDic];
}

- (NSUInteger) getSwitchCount
{
    return _nSwitchCount;
}

//move
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
  BOOL bMoveable = _nSetUnit <= _nWgtLimitIdx;// || _nSetUnit == 201 || _nSetUnit == 202;
  if(!bMoveable)
      return;
    
    UITouch *touch = [touches anyObject];
    CGPoint pt =[touch locationInView:self];
    if (CGRectContainsPoint(self.window.frame, pt)) {
        //dragging = YES;
        _xViewPos = pt.x;
    }
    //_lblMeasUnit.text = @"begin";
}

-(void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
  BOOL bMoveable = _nSetUnit <= _nWgtLimitIdx;// || _nSetUnit == 201 || _nSetUnit == 202;
  if(!bMoveable)
    return;
    
  UITouch *touch = [touches anyObject];
  CGPoint pt =[touch locationInView:self];
  
  CGRect frame = self.frame;
  frame.origin.x =  self.frame.origin.x + pt.x - _xViewPos;
  self.frame = frame;
  //self.bounds = frame;
  
  [_delegate moveOtherViewCtrl:self];
}

- (void) touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
  BOOL bMoveable = _nSetUnit <= _nWgtLimitIdx;// || _nSetUnit == 201 || _nSetUnit == 202;
  
  CGFloat fMoveDist = _xViewPos - self.frame.origin.x;
  if(_nSetUnit == _nWgtLimitIdx || _nSetUnit == 202)
    fMoveDist = -fMoveDist;
  else if(!bMoveable)
    return;
  
  
  if(fMoveDist > self.frame.size.width / 10.0) {
    [_delegate moveOutForNextOne:self];
  }
  else {
    self.center = _ptCenterInit;
  }
  //self.hidden = YES;
}
@end
